package org.rockyang.shardingjdbc.base.algorithm.db;


import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.shardingsphere.api.sharding.complex.ComplexKeysShardingAlgorithm;
import org.apache.shardingsphere.api.sharding.complex.ComplexKeysShardingValue;
import org.rockyang.shardingjdbc.base.exception.BizException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;

/**
 * 自定义分库算法，这里实现一个最简单的分库算法
 * @author yangjian
 */
@Slf4j
public class DbComplexKeysShardingAlgorithm implements ComplexKeysShardingAlgorithm<Long> {

    private static final String ORDER_ID_COLUMN ="order_id";
    private static final String USER_ID_COLUMN ="user_id";

    // 取模因子
    public static final Integer MODE_FACTOR = 1331;

    public static void main(String[] args) {
        System.out.println(Long.valueOf("1769891364989964288"));
    }

    @Override
    public Collection<String> doSharding(Collection<String> collection, ComplexKeysShardingValue<Long> complexKeysShardingValue) {
        log.info("--------------------------------------------------");
         log.info("本次操作涉及的-逻辑库列表:"+ JSONObject.toJSONString(collection));
        Map<String, Collection<Long>> columnNameAndShardingValuesMap = complexKeysShardingValue.getColumnNameAndShardingValuesMap();
         log.info("本次操作涉及的-分库字段实际参数:"+columnNameAndShardingValuesMap);
        Collection<Long> orderIdCollection = columnNameAndShardingValuesMap.get(ORDER_ID_COLUMN);
        if(CollectionUtil.isEmpty(orderIdCollection)){
            log.error("分片键值不能为空:"+ORDER_ID_COLUMN);
            log.error("分片键值不能为空:"+ORDER_ID_COLUMN);
            log.error("分片键值不能为空:"+ORDER_ID_COLUMN);
            throw new BizException("分片键值不能为空:"+ORDER_ID_COLUMN);
        }
        Collection<Long> userIdCollection  = columnNameAndShardingValuesMap.get(USER_ID_COLUMN);
        if(CollectionUtil.isEmpty(userIdCollection)){
            log.error("分片键值不能为空:"+USER_ID_COLUMN);
            log.error("分片键值不能为空:"+USER_ID_COLUMN);
            log.error("分片键值不能为空:"+USER_ID_COLUMN);
            throw new BizException("分片键值不能为空:"+USER_ID_COLUMN);
        }

        List<Long> orderIdList = new ArrayList<>(orderIdCollection);
        List<Long> userIdList = new ArrayList<>(userIdCollection);
        Long orderId  =orderIdList.get(0);
        Long userId = userIdList.get(0);

        // 取模是为了防止溢出
        Long orderIdShardingCountValue =(Math.abs(orderId) % MODE_FACTOR);
        log.info("分库-orderIdShardingCountValue:"+orderIdShardingCountValue);
        // 取模是为了防止溢出
        Long userIdShardingCountValue =(Math.abs(userId) % MODE_FACTOR);
        log.info("分库-userIdIdShardingCountValue:"+userIdShardingCountValue);

        Long shardingCountValue = orderIdShardingCountValue + userIdShardingCountValue;
        log.info("分库-分片键值合:"+shardingCountValue);


        Long shardingIndex= shardingCountValue % collection.size();
        List<String> shardingResults = new ArrayList<>();
        for (String name : new ArrayList<>(collection)) {
            // get logic datasource index suffix
            String nameSuffix = name.substring(name.length() - 1);
            if (nameSuffix.equals(shardingIndex.toString())) {
                shardingResults.add(name);
                log.info("本次操作路由'库'结果:"+name);
                break;
            }
        }

        return shardingResults;
    }




}